%% @doc 新闻聚合接口实现

-module(newspack_api).
-export([
  register/1,
  refresh/2,
  list/0,
  cache_password/2
]).
-include("cloap_record.hrl").


% =========================================================
% @doc
% 注册 API, 重复内容不允许多次注册
% @end
% =========================================================
register(Argv) ->
    try
        #{<<"title">> := Title, <<"category">> := Category} = Argv,

        case newspack_store:lookup_spider(Category, Title) of
            {ok, Result}    ->
                message(ok, #{<<"id">> => Result#news_spider.id});
            {error, _} ->
                {ok, Result2} = newspack_store:register(Category, Title),
                message(ok, #{<<"id">> => Result2#news_spider.id})
        end
    catch
        error:{badmatch, _X} -> message(error, <<"参数错误"/utf8>>)
    end.



% =========================================================
% @doc
% 登记新闻条目, 每次登记时将删除以前的内容，
% 如果内容清单为空，则忽略而不会删除
% @end
% =========================================================
refresh(SpiderId, Argv) ->

  case length(Argv) of
    0 ->  message(ok, <<"内容为空，新闻条目未更新"/utf8>>);
    _ ->
      newspack_store:delete_items(SpiderId),

      lists:map(
        fun(Elem) -> newspack_store:insert_item(SpiderId, Elem) end,
        Argv
      ),

      message(ok, <<"新闻条目已经更新"/utf8>>)
  end.


% =========================================================
% @doc
% 缓存用户口令，或者取出用户口令
% @end
% =========================================================
cache_password(Login, Passwd) ->
    try
        newspack_store:write_passwd(Login, Passwd),
        message(ok, <<"口令已经更新"/utf8>>)
    catch
        _:_ -> message(error, <<"口令更新失败"/utf8>>)
    end.



% =========================================================
% @doc
% 登记新闻条目, 每次登记时将删除以前的内容，
% 如果内容清单为空，则忽略而不会删除
% @end
% =========================================================
list() ->
  [
    maps:merge(record_to_map(news_spider, Elem), #{<<"items">> => list_items(Elem#news_spider.id) }) || Elem <- newspack_store:lookall_spider()
  ].


list_items(SpiderId) ->
  [record_to_map(news_item, Elem) || Elem <- newspack_store:lookall_item(SpiderId)].




% =========================================================
% @private
% =========================================================
message(ok, Msg) ->
  #{<<"ok">> => Msg};
message(error, Msg) ->
  #{<<"error">> => Msg}.


record_to_map(news_spider, Elem) ->
  record_to_map(record_info(fields, news_spider), Elem);
record_to_map(news_item, Elem) ->
  record_to_map(record_info(fields, news_item), Elem);
record_to_map(RecordInfo, Elem) ->
  Hash = lists:zip(RecordInfo, tl(tuple_to_list(Elem))),
  lists:foldl(
    fun({Key, Value}, Map) -> maps:put(list_to_binary(atom_to_list(Key)), Value, Map) end,
    #{},
    Hash).
